import {
    HubConnection,
    HubConnectionBuilder,
    HubConnectionState,
    LogLevel,
  } from '@microsoft/signalr'
  // import { request, type BaseResponse } from './request'
  import {request} from './request'
  import { useUserStore } from '../store/modules/user'
  // import {type BaseResponse } from '../types/global'
  
  const baseHubUrl = import.meta.env.VITE_BASE_HUB_URL
  
  export class TransmissionHub {
    private connection: HubConnection
  
    /**
     * 回调列表
     * key: 模块
     * value: 回调
     */
    private readonly callbackList = new Map<string, TransmissionHubCallback>()
  
    private readonly pendingInitList: InitData[] = []
  
    constructor() {
      const userStore = useUserStore()
  
      this.connection = new HubConnectionBuilder()
        .configureLogging(LogLevel.Error)
        .withUrl(`${baseHubUrl}hubs/transmission`, {
          accessTokenFactory: () => userStore.token,
        })
        .withAutomaticReconnect({
          nextRetryDelayInMilliseconds: retryContext => {
            // console.log('reconn', retryContext)
            return 10_000
          },
        })
        .build()
  
      this.connection.on('error', (data: ErrorResData) => {
        // console.log('TransmissionHub: error', data)
        const cb = this.callbackList.get(data.module)
        if (cb?.onError) {
          cb.onError(data.message)
        }
      })
      this.connection.on('inited', (data: InitedResData) => {
        // console.log('TransmissionHub: inited', data)
        const cb = this.callbackList.get(data.module)
        if (cb?.onInited) {
          cb.onInited(data)
        }
      })
      this.connection.on('data', (data: PayloadResData) => {
        // console.log('TransmissionHub: data', data)
        const cb = this.callbackList.get(data.module)
        if (cb?.onData) {
          cb.onData(data.payload || '')
        }
      })
  
      // // 心跳，从服务端确认是否是有效连接
      // this.connection.on('ping', () => {
      //   this.connection.invoke('ping')
      // })
  
      this.connection.onreconnected(() => {
        // console.log('TransmissionHub: 已重新连接', this.connection.connectionId)
  
        const list = [...this.callbackList.values()]
        list.forEach(x => {
          x.onReconnected && x.onReconnected()
        })
      })
    }
  
    async start() {
      if (
        this.connection.state === HubConnectionState.Connected ||
        this.connection.state === HubConnectionState.Connecting
      ) {
        return
      }
  
      await this.connection.start()
  
      // console.log('TransmissionHub: 建立链接', this.connection.connectionId)
  
      // console.log(
      //   'TransmissionHub: 已建立链接，将待初始化数据进行初始化',
      //   this.connection.connectionId,
      //   this.pendingInitList.length,
      // )
      if (this.pendingInitList.length > 0) {
        for (const item of this.pendingInitList) {
          await this.init(item)
        }
      }
    }
    async close() {
      // console.log('TransmissionHub: close', this.connection.connectionId)
  
      this.callbackList.clear()
  
      await this.connection.stop()
    }
  
    /**
     * 初始化模块
     * @param initData
     */
    async init(initData: InitData) {
      if (this.connection.state !== HubConnectionState.Connected) {
        // throw new Error('连接尚未初始化')
        // 加入到待初始化列表
        this.pendingInitList.push(initData)
        return
      }
  
      await this.connection.invoke('init', initData)
    }
  
    /**
     * 监听模块回调
     * @param module 模块
     * @param cb 回调
     */
    on(module: string, cb: TransmissionHubCallback) {
      // console.log('TransmissionHub: 注册模块回调', module, cb)
      if (this.callbackList.has(module)) {
        console.warn('TransmissionHub: 重复注册模块回调')
      }
  
      this.callbackList.set(module, cb)
    }
    /**
     * 移除模块回调
     * @param module
     * @param isDelete 是否从服务端删除
     */
    remove(module: string, isDelete?: boolean) {
      this.callbackList.delete(module)
      if (isDelete && this.connection.state === HubConnectionState.Connected) {
        this.connection.invoke('remove', module)
      }
    }
  }
  export type Response<T = any> = {
    code: number
    message: string
    data: T
    count?: number
  }
  
  export type BaseResponse<T = any> = Promise<Response<T>>
  
  /**
   * 发送数据
   */
  export const sendTransmissionData = (module: string, id: string, payload: string) => {
    return request<BaseResponse>(
      {
        url: 'hubs/transmission/send',
        method: 'post',
        data: {
          module,
          id,
          payload,
        },
      },
      {
        isGetDataDirectly: false,
      },
    )
  }
  
  /**
   * 初始化数据
   */
  type InitData = {
    /**
     * 模块名称
     */
    module: string
    /**
     * 过期秒数
     */
    expirySeconds: number
    /**
     * 唯一标识
     */
    id?: string
    /**
     * 是否允许匿名访问
     */
    allowAnonymous?: boolean
    /**
     * 是否私有：仅允许自己
     */
    isPrivate?: boolean
  }
  
  /**
   * 初始化成功响应
   */
  export type InitedResData = {
    module: string
    /**
     * 唯一标识
     */
    id: string
    /**
     * 过期时间：毫秒时间戳
     */
    expiry: number
  }
  
  type PayloadResData = {
    module: string
    payload: string | null | undefined
  }
  
  type ErrorResData = {
    module: string
    message: string
  }
  
  type TransmissionHubCallback = {
    /**
     * 当发生错误时回调错误信息
     */
    onError?: (message: string) => void
  
    /**
     * 初始化成功回调
     */
    onInited?: (data: InitedResData) => void
  
    /**
     * 数据接收
     */
    onData?: (payload: string) => void
  
    /**
     * 重新连接
     */
    onReconnected?: () => void
  }
  